package com.google.code.cubeirc.ui;

import java.io.File;

import lombok.Getter;
import lombok.Setter;

import org.apache.log4j.Level;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.pircbotx.DccFileTransfer;

import com.google.code.cubeirc.base.BaseTab;
import com.google.code.cubeirc.common.ApplicationInfo;
import com.google.code.cubeirc.common.Utils;
import com.google.code.cubeirc.connection.Connection;
import com.google.code.cubeirc.queue.MessageQueueEnum;
import com.google.code.cubeirc.queue.MessageQueueEvent;

public class DownloadsForm extends BaseTab {

	private Table table;

	@Setter @Getter
	private Thread thDwMonitor;



	public DownloadsForm(Composite composite, int style, String name) {
		super(composite, style, name);

		setLayout(new FormLayout());

		table = new Table(this, SWT.BORDER | SWT.FULL_SELECTION);
		FormData fd_table = new FormData();
		fd_table.top = new FormAttachment(0, 10);
		fd_table.left = new FormAttachment(0, 10);
		fd_table.bottom = new FormAttachment(100, -10);
		fd_table.right = new FormAttachment(100, -40);
		table.setLayoutData(fd_table);
		table.setHeaderVisible(true);
		table.setLinesVisible(true);

		TableColumn tblclmnSender = new TableColumn(table, SWT.NONE);
		tblclmnSender.setWidth(100);
		tblclmnSender.setText("Sender");

		TableColumn tblclmnDestinantion = new TableColumn(table, SWT.NONE);
		tblclmnDestinantion.setWidth(100);
		tblclmnDestinantion.setText("Destinantion");

		TableColumn tblclmnFilename = new TableColumn(table, SWT.NONE);
		tblclmnFilename.setWidth(100);
		tblclmnFilename.setText("Filename");

		TableColumn tblclmnSize = new TableColumn(table, SWT.NONE);
		tblclmnSize.setWidth(60);
		tblclmnSize.setText("Size");

		TableColumn tblclmnSpeed = new TableColumn(table, SWT.NONE);
		tblclmnSpeed.setWidth(74);
		tblclmnSpeed.setText("Speed");

		TableColumn tblclmnProgress = new TableColumn(table, SWT.NONE);
		tblclmnProgress.setWidth(142);
		tblclmnProgress.setText("Progress");

		TableColumn tblclmnType = new TableColumn(table, SWT.NONE);
		tblclmnType.setWidth(100);
		tblclmnType.setText("Type");

		watchThread();


	}





	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	/**
	 * Adds the download.
	 *
	 * @param trans the trans
	 */
	private void addDownload(final DccFileTransfer trans)
	{
		asyncExec(new Runnable() {

			@Override
			public void run() {
				TableItem ti = new TableItem(table, SWT.NONE);				
				if (trans.isIncoming())
				{
					ti.setText(0, trans.getUser().getNick());
					ti.setText(1, Connection.userInfo.getNick());
					ti.setText(6, "<< RECEIVING");
				}
				else
				{
					ti.setText(1, trans.getUser().getNick());
					ti.setText(0, Connection.userInfo.getNick());
					ti.setText(6, ">> SENDING");
				}
				ti.setText(2, trans.getFile().getName());
				ti.setText(3, Utils.reportTraffic(trans.getSize()));
				ti.setText(4, Utils.reportTraffic(trans.getTransferRate())+ "/s");
				ProgressBar pb = new ProgressBar(table, SWT.SMOOTH);
				pb.addPaintListener(new PaintListener() {

					@Override
					public void paintControl(PaintEvent e) {
						if (e.getSource() instanceof ProgressBar)
						{
							ProgressBar pb = (ProgressBar)e.getSource();

							String string =  (pb.getSelection() * 1.0 / (pb.getMaximum()-pb.getMinimum()) * 100) + "%";
							Point point = pb.getSize();
							FontMetrics fontMetrics = e.gc.getFontMetrics();
							int width =  fontMetrics.getAverageCharWidth() * string.length();
							int height = fontMetrics.getHeight();

							e.gc.setForeground(getShell().getDisplay().getSystemColor(SWT.COLOR_BLACK));
							e.gc.drawString (string, (point.x-width)/2 , (point.y-height)/2, true);

						}
					}
				});


				ti.setData("trans", trans);
				ti.setData("progress", pb);
				TableEditor editor = new  TableEditor(table);
				editor.grabHorizontal = editor.grabVertical  = true;
				editor.setEditor(pb,ti, 5);


				Utils.checkDirectoryExist(ApplicationInfo.DCC_DEFAULT_DIRECTORY, true);

				trans.receive(new File(ApplicationInfo.DCC_DEFAULT_DIRECTORY + trans.getFile().getName()), true);
				addDebug(Level.INFO, "Start to receive files %s",ApplicationInfo.DCC_DEFAULT_DIRECTORY + trans.getFile().getName());
			}
		});
	}

	/**
	 * Watch thread.
	 */
	private void watchThread()
	{
		setThDwMonitor(new Thread(new Runnable() {

			@Override
			public void run() {
				while (true)
				{
					try {
						Thread.sleep(500);
						updateStatus();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

				}
			}
		}));

		getThDwMonitor().setName("Thread Download monitor");
		getThDwMonitor().start();
	}

	/**
	 * Update status.
	 */
	private void updateStatus()
	{
		asyncExec(new Runnable() {

			@Override
			public void run() {
				if (table.getItemCount() > 0)
				{
					TableItem[] itms = table.getItems();

					for (int i=0;i<itms.length;i++)
					{
						if (itms[i].getText(5) != "COMPLETED")
						{
							DccFileTransfer trans = (DccFileTransfer)itms[i].getData("trans");
							itms[i].setText(4, Utils.reportTraffic(trans.getTransferRate()) + "/s");
							ProgressBar pb = (ProgressBar)itms[i].getData("progress"); 					
							pb.setSelection((int)trans.getProgressPercentage());

							if (trans.getProgress() >= trans.getSize())		
							{
								itms[i].setText(6, "COMPLETED"); 
								addDebug(Level.INFO, "File %s send/receive completed", trans.getFile().getName());
								//MessageQueue.addQueue(MessageQueueEnum.DCC_FILE_COMPLETED, trans.getUser(), null, null, null, trans);
							}
						}

					}

				}

			}

		});

	}

	private void askDownload(final DccFileTransfer trans)
	{
		MessageBox mb = new MessageBox(getShell(), SWT.YES | SWT.NO | SWT.ICON_QUESTION);
		mb.setText("Incoming file transfer!");
		mb.setMessage(String.format("User %s want to send you file %s\nAccept?", trans.getUser().getNick(),trans.getFile().getName()));
		if (mb.open() == SWT.YES)
		{
			addDownload(trans);
		}
	}

	@Override
	public void actionPerformed(MessageQueueEvent e) {
		if (e.getMsgtype() == MessageQueueEnum.DCC_FILE_INCOMING)
		{
			askDownload((DccFileTransfer)e.getData());
		}

		if (e.getMsgtype() == MessageQueueEnum.DCC_FILE_OUTCOMING)
			addDownload((DccFileTransfer)e.getData());

		super.actionPerformed(e);
	}

	@Override
	public boolean Close() {
		getThDwMonitor().interrupt();
		setThDwMonitor(null);
		return super.Close();
	}


}
